package com.pay.ioopos.fragment;

import com.aggregate.pay.sanstar.SanstarApiFactory;
import com.aggregate.pay.sanstar.bean.PayOrderData;
import com.aggregate.pay.sanstar.bean.PayOrderResult;
import com.aggregate.pay.sanstar.bean.PayQueryData;
import com.aggregate.pay.sanstar.bean.PayQueryResult;
import com.aggregate.pay.sanstar.bean.Result;
import com.aggregate.pay.sanstar.enums.PayMethod;
import com.aggregate.pay.sanstar.enums.PayType;
import com.aggregate.pay.sanstar.support.Client;
import com.aggregate.pay.sanstar.support.Merch;
import com.pay.ioopos.ApiFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;

public class PayIngFragment extends PayIngAbstract {
    private Merch merch;
    private String orderNo;
    private String channelOrderNo;

    public PayIngFragment(PayFinishListener listener, String barcode, String amount) {
        super(listener, barcode, amount);
        merch = ApiFactory.initApi();
    }

    public String getOrderNo() {
        return orderNo;
    }

    @Override
    public void execute() throws Exception {
        super.execute();

        if (!barcode.matches("[0-9]{10,30}")) {
            showPayFail("不支持该付款码");
            return;
        }

        PayType payType;
        if (isAlipayPay()) {
            payType = PayType.ALIPAY;
        } else if (isWeixinPay()) {
            payType = PayType.WEIXIN;
        } else if(isUnionPay()) {
            payType = PayType.UNIONPAY;
        } else {
            showPayFail("不支持该付款码");
            return;
        }

        orderNo = ApiFactory.generateOrderNo();

        Integer amount = new BigDecimal(this.amount).multiply(new BigDecimal("100")).setScale(0, RoundingMode.DOWN).intValue();

        PayOrderData apiData = new PayOrderData();
        apiData.setAmount(amount);
        apiData.setAuthCode(barcode);
        apiData.setCusOrderNo(orderNo);
        apiData.setGoodsName("食堂");
        apiData.setOrderTime(new Date());
        apiData.setPayMethod(PayMethod.SCAN);
        apiData.setPayType(payType);
        apiData.setRemark("食堂消费");

        Client<PayOrderData, PayOrderResult> client = SanstarApiFactory.payOrder(merch);

        Result<PayOrderResult> apiResult = client.execute(apiData);

        if (apiResult.getStatus() != Result.Status.OK) {
            if (apiResult.getCode().equals("C9998")) {
                showToast("网络异常：" + apiResult.getMessage());
                speak("网络异常");
                query();
            } else if (apiResult.getCode().equals("C9999")) {
                showToast("支付异常：" + apiResult.getMessage());
                query();
            } else {
                showPayFail("支付返回：[" + apiResult.getCode() + "]" + apiResult.getMessage());
            }
            return;
        }

        PayOrderResult payResult = apiResult.getData();
        channelOrderNo = payResult.getOrderNo();
        switch (payResult.getPayStatus()) {
            case FAIL:
                showPayFail(payResult.getPayDesc());
                break;
            case SUCCESS:
                showPaySuccess(orderNo, channelOrderNo);
                break;
            case PAYING:
                showPayPwd();
            default:
                query();
                break;
        }

    }

    private void query() throws Exception {

        PayQueryData apiData = new PayQueryData();
        apiData.setCusOrderNo(orderNo);
        apiData.setOrderNo(channelOrderNo);

        Client<PayQueryData, PayQueryResult> client = SanstarApiFactory.payQuery(merch);
        Result<PayQueryResult> apiResult;
        PayQueryResult queryResult;

        long startTime = System.currentTimeMillis();
        int sleepTime = 5000;
        long diff;

        query: while(true) {

            Thread.sleep(sleepTime);

            diff = (System.currentTimeMillis() - startTime)/1000;
            if (diff >= 120) {
                showPayExpired();
                break;
            } else if (diff >= 60) {
                sleepTime = 7000;
            } else if (diff >= 30) {
                sleepTime = 6000;
            }

            apiResult = client.execute(apiData);

            if (apiResult.getStatus() != Result.Status.OK) {
                if (apiResult.getCode().equals("C9998")) {
                    showToast("网络异常：" + apiResult.getMessage());
                    speak("网络异常");
                } else if (apiResult.getCode().equals("C9999")) {
                    showToast("查询异常：" + apiResult.getMessage());
                } else {
                    showToast("查询返回：[" + apiResult.getCode() + "]" + apiResult.getMessage());
                }
                continue;
            }

            queryResult = apiResult.getData();

            switch (queryResult.getPayStatus()) {
                case PAYING:
                    showPayPwd();
                    break;
                case FAIL:
                    showPayFail(queryResult.getPayDesc());
                    break query;
                case SUCCESS:
                    showPaySuccess(orderNo, channelOrderNo);
                    break query;
            }
        }
    }
}
